/*
 * Copyright (c) 2018-2999 北京小象智慧信息科技有限公司 All rights reserved.
 *
 * https://www.xiaoxiangai.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.yami.shop.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yami.shop.PromotionStrategyService;
import com.yami.shop.bean.app.dto.CouponDto;
import com.yami.shop.bean.app.dto.OrderCountData;
import com.yami.shop.bean.app.dto.OrderStaticsDto;
import com.yami.shop.bean.app.dto.ShopCartOrderMergerDto;
import com.yami.shop.bean.dto.ShopDetailSalesDto;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.enums.OrderType;
import com.yami.shop.bean.event.CancelOrderEvent;
import com.yami.shop.bean.event.FinishOrderEvent;
import com.yami.shop.bean.event.ReceiptOrderEvent;
import com.yami.shop.bean.event.SubmitOrderEvent;
import com.yami.shop.bean.meituan.*;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.param.OrderParam;
import com.yami.shop.bean.param.ParamBuilder;
import com.yami.shop.bean.pay.Records;
import com.yami.shop.bean.pay.RefundGoodsDto;
import com.yami.shop.bean.pt.YxCtjl;
import com.yami.shop.bean.pt.YxPtgl;
import com.yami.shop.bean.pt.YxPtsp;
import com.yami.shop.common.util.*;
import com.yami.shop.dao.*;
import com.yami.shop.service.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.yami.shop.dao.YxPtglMapper;
import com.yami.shop.dao.YxCtjlMapper;
import com.yami.shop.dao.YxPtspMapper;
import com.yami.shop.dao.UserMapper;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lgh on 2018/09/15.
 */
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private OrderSettlementService orderSettlementService;

    @Autowired
    private OrderRefundService orderRefundService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CheckAccountService checkAccountService;

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    @Autowired
    private ShopDetailService shopDetailService;

    @Autowired
    private RebateRecordsService rebateRecordsService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private PayService payService;

    @Autowired
    private UserService userService;

    @Autowired
    private CouponRecordMapper couponRecordMapper;

    @Autowired
    private RebateRecordsMapper rebateRecordsMapper;

    @Autowired
    private ConfigService configService;

    @Autowired
    private UserAddrOrderService userAddrOrderService;

    @Autowired
    private UserAddrService  userAddrService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private YxPtglMapper yxPtglMapper;

    @Autowired
    private YxCtjlMapper yxCtjlMapper;

    @Autowired
    private YxPtspMapper yxPtspMapper;

    @Autowired
    private  Snowflake snowflake;

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private BasketService basketService;

    @Autowired
    private  CouponRecordService couponRecordService;

    @Autowired
    private ProductService productService;

    private static String authorization;

    @Autowired
    private ShopTypeService shopTypeService;

	@Autowired
    private UserMapper userMapper;

	@Autowired
    private OldUserService oldUserService;

	@Autowired
    private PromotionStrategyService promotionStrategyService;

    @Override
    public Order getOrderByOrderNumber(String orderNumber) {
        return orderMapper.getOrderByOrderNumber(orderNumber);
    }

    @Override
    @CachePut(cacheNames = "ConfirmOrderCache", key = "#userId")
    public ShopCartOrderMergerDto putConfirmOrderCache(String userId, ShopCartOrderMergerDto shopCartOrderMergerDto) {
        return shopCartOrderMergerDto;
    }

    @Override
    @Cacheable(cacheNames = "ConfirmOrderCache", key = "#userId")
    public ShopCartOrderMergerDto getConfirmOrderCache(String userId) {
        return null;
    }

    @Override
    @CacheEvict(cacheNames = "ConfirmOrderCache", key = "#userId")
    public void removeConfirmOrderCache(String userId) {
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Order> submit(String userId, ShopCartOrderMergerDto mergerOrder,String tjr,String pickupTime,String ptglid,String purchaseType,Long prodId) {
        List<Order> orderList = new ArrayList<>();
        // 通过事务提交订单
        eventPublisher.publishEvent(new SubmitOrderEvent(mergerOrder, orderList,tjr,pickupTime,ptglid,purchaseType,prodId));

        // 插入订单
        orderList.forEach(order -> orderMapper.insert(order));
        List<OrderItem> orderItems = orderList.stream().flatMap(order -> order.getOrderItems().stream()).collect(Collectors.toList());
        // 插入订单项，返回主键
        orderItemMapper.insertBatch(orderItems);


        return orderList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delivery(Order order) {
        orderMapper.updateById(order);
        // 发送用户发货通知
        Map<String, String> params = new HashMap<>(16);
        params.put("orderNumber", order.getOrderNumber());
//		Delivery delivery = deliveryMapper.selectById(order.getDvyId());
//		params.put("dvyName", delivery.getDvyName());
//		params.put("dvyFlowId", order.getDvyFlowId());
//		smsLogService.sendSms(SmsType.NOTIFY_DVY, order.getUserId(), order.getMobile(), params);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refund(Order order) {
        orderMapper.updateById(order);
        // 发送用户退款通知
        Map<String, String> params = new HashMap<>(16);
        params.put("orderNumber", order.getOrderNumber());

        //查询退款订单
        List<Order> orders = orderService.selectByOrderNumber(order.getOrderNumber());
        /**
         * 退款信息存入退款表中
         */
        OrderSettlement orderSettlement = orderSettlementService.getSettlementByOrderId(order.getOrderNumber());
        OrderRefund orderRefund = new OrderRefund();
        OrderItem orderItemList;
        orderItemList = orders.get(0).getOrderItems().get(0);
        Order order1 = orders.get(0);
        orderRefund.setShopId(order1.getShopId());
        orderRefund.setOrderId(order1.getOrderId());
        orderRefund.setOrderNumber(order1.getOrderNumber());
        orderRefund.setOrderAmount(order1.getActualTotal());
        orderRefund.setRefundAmount(order1.getActualTotal());
        orderRefund.setRefundSn(orderSettlement.getPayNo());
        orderRefund.setOrderItemId(orderItemList.getOrderItemId());
        orderRefund.setFlowTradeNo(orderSettlement.getPayNo());
        orderRefund.setOutRefundNo(orderSettlement.getBizPayNo());
        orderRefund.setPayType(orderSettlement.getPayType());
        orderRefund.setUserId(orderSettlement.getUserId());
        orderRefund.setRefundAmount(orderSettlement.getPayAmount());
        orderRefund.setRefundReason(order.getRefundReason());
        orderRefund.setRefundImg(order.getRefundImg());
        orderRefund.setRefundExplain(order.getRefundExplain());
        orderRefund.setPhone(order.getPhone());
        if(order.getRefundState()==2){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(2);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(1);
        }else if(order.getRefundState()==1){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(1);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(0);
        }else if(order.getRefundState()==3){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(3);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(-1);
        }
        /**
         * 1：仅退款 2：退货退款
         */
        orderRefund.setApplyType(1);
        orderRefund.setApplyTime(new Date());
        orderRefundService.save(orderRefund);

//		Delivery delivery = deliveryMapper.selectById(order.getDvyId());
//		params.put("dvyName", delivery.getDvyName());
//		params.put("dvyFlowId", order.getDvyFlowId());
//		smsLogService.sendSms(SmsType.NOTIFY_DVY, order.getUserId(), order.getMobile(), params);

    }

    @Override
    public List<Order> listOrderAndOrderItems(Integer orderStatus, DateTime lessThanUpdateTime) {
        return orderMapper.listOrderAndOrderItems(orderStatus, lessThanUpdateTime);
    }

    @Override
    public List<Order> OrderAndOrderItems(Integer orderStatus,String orderNumber) {
        return orderMapper.OrderAndOrderItems(orderStatus,orderNumber);
    }

    @Override
    public List<Order> selectByOrderNumber(String orderNumber) {
        return orderMapper.selectByOrderNumber(orderNumber);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelOrders(List<Order> orders) {
        for (int i=0;i<orders.size();i++){
            orderMapper.cancelOrders(orders.get(i));
        }

        //取消订单后返还优惠券
        couponRecordMapper.cancelOrders(orders);
        List<OrderItem> allOrderItems = new ArrayList<>();
        for (Order order : orders) {
            List<OrderItem> orderItems = order.getOrderItems();
            allOrderItems.addAll(orderItems);
            eventPublisher.publishEvent(new CancelOrderEvent(order));
        }
        if (CollectionUtil.isEmpty(allOrderItems)) {
            return;
        }
        Map<Long, Integer> prodCollect = new HashMap<>(16);
        allOrderItems.stream().collect(Collectors.groupingBy(OrderItem::getProdId)).forEach((prodId, orderItems) -> {
            int prodTotalNum = orderItems.stream().mapToInt(OrderItem::getProdCount).sum();
            prodCollect.put(prodId, prodTotalNum);
        });
        productMapper.returnStock(prodCollect);

        Map<Long, Integer> skuCollect = new HashMap<>(16);
        allOrderItems.stream().collect(Collectors.groupingBy(OrderItem::getSkuId)).forEach((skuId, orderItems) -> {
            int prodTotalNum = orderItems.stream().mapToInt(OrderItem::getProdCount).sum();
            skuCollect.put(skuId, prodTotalNum);
        });
        skuMapper.returnStock(skuCollect);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void confirmOrder(List<Order> orders) {
        orderMapper.confirmOrder(orders);
        for (Order order : orders) {
            eventPublisher.publishEvent(new ReceiptOrderEvent(order));
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void finishOrder(List<Order> orders) {
        //处理用户订单返利情况
        rebateRecordsService.dealRebateAfterOrder(orders);
        orderMapper.finishOrder(orders);
        for (Order order : orders) {
            CheckAccount checkAccount=checkAccountService.getByOrderNumber(order.getOrderNumber());
            if(checkAccount!=null&&!"".equals(checkAccount)){
                return;
            }else{
                //获得该订单的返利
                String orderNumber = order.getOrderNumber();
                RebateRecords rebateRecords = rebateRecordsMapper.getRebateRecords(orderNumber);
                Double rebateMoney = 0.00;
                if(rebateRecords!=null){
                    rebateMoney =  rebateRecords.getAmount();
                }
                CheckAccount checkAccount1 = new CheckAccount();
                checkAccount1.setOrderNumber(order.getOrderNumber());
                checkAccount1.setType("入账");
                checkAccount1.setPayAmount(order.getActualTotal());
                checkAccount1.setTime(new Date());
                checkAccount1.setShopid(order.getShopId());
                checkAccount1.setRebateMoney(rebateMoney);
                checkAccount1.setDeliveryPrice(order.getDeliveryPrice());

                //查询当前店铺的类型,获取该订单的手续费
                Long shopId =order.getShopId();
                ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(shopId);
                Double configValue = 0.00;
                if(shopDetail!=null) {
                    ShopType shopType = shopTypeService.getById(shopDetail.getShopTypeId());
                    if(shopType!=null){
                        configValue = shopType.getRate();
                    }
                }
             //   String configValue = configService.getValue("service_fee");

                Double serviceFee = null;
                if(null!=configValue&&!"".equals(configValue)) {
                     serviceFee = Arith.mul(order.getActualTotal(),configValue );
                }
                checkAccount1.setService_fee(serviceFee);
                //计算可提现金额
                Double withdrawalAmount = Arith.sub(Arith.sub(order.getActualTotal(),rebateMoney),serviceFee);
                //如果有快递费的话,还需要减去快递费
                BigDecimal deliveryPrice = new BigDecimal(order.getDeliveryPrice());
                if(deliveryPrice.compareTo(new BigDecimal("0"))>0){
                    withdrawalAmount = Arith.sub(withdrawalAmount,order.getDeliveryPrice());
                }
                checkAccount1.setWithdrawalAmount(withdrawalAmount);
                checkAccountService.save(checkAccount1);

               // ShopDetail shopDetail = shopDetailService.getShopDetailByShopId(order.getShopId());
                Double account = shopDetail.getAccount();
                Double rebteAccount = shopDetail.getRebateMoney();
                Double cashmoney = shopDetail.getCashMoney();
                Double delivery = shopDetail.getDeliveryPrice();
                if(account==null){
                    account=0.00;
                }
                if(rebteAccount==null){
                    rebteAccount = 0.00;
                }

                if(cashmoney==null){
                    cashmoney = 0.00;
                }

                if(delivery==null){
                    delivery = 0.00;
                }

                Double sumAccount = Arith.add(order.getTotal() , account);
                shopDetail.setAccount(sumAccount);
                Double sumRebateAccount = Arith.add(rebteAccount , rebateMoney);
                shopDetail.setRebateMoney(sumRebateAccount);
                Double sumCashMoney = Arith.add(cashmoney,withdrawalAmount);
                shopDetail.setCashMoney(sumCashMoney);
                Double sumDeliveryPrice = Arith.add(delivery,order.getDeliveryPrice());
                shopDetail.setDeliveryPrice(sumDeliveryPrice);
                shopDetailService.updateById(shopDetail);
            }
            eventPublisher.publishEvent(new FinishOrderEvent(order));
        }

    }

    @Override
    public List<Order> listOrdersDetialByOrder(Order order, Date startTime, Date endTime) {
        return orderMapper.listOrdersDetialByOrder(order, startTime, endTime);
    }

    @Override
    public IPage<Order> pageOrdersDetialByOrderParam(Page<Order> page, OrderParam orderParam) {
        List<Order> orderList = orderMapper.listOrdersDetialByOrderParam(new PageAdapter(page), orderParam);
        if(orderList.size()>0){
            for(Order order:orderList){
                 Long ptglid = order.getPtglid();
                 YxPtgl yxPtgl = yxPtglMapper.selectYxPtglById(ptglid);
                 if(yxPtgl!=null){
                     order.setPtstatus(yxPtgl.getStatus());
                 }
            }
        }
        page.setRecords(orderList);
        page.setTotal(orderMapper.countOrderListByOrderParam(orderParam));
        return page;
    }

    @Override
    public IPage<OrderRefund> pageOrdersRefundByOrderParam(Page<OrderRefund> page, OrderParam orderParam) {
        page.setRecords(orderMapper.listOrdersRefundByOrderParam(new PageAdapter(page), orderParam));
        page.setTotal(orderMapper.countlistOrdersRefundByOrderParam(orderParam));
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrders(List<Order> orders) {
        orderMapper.deleteOrders(orders);
    }

    @Override
    public OrderCountData getOrderCount(String userId) {
        return orderMapper.getOrderCount(userId);
    }

    /**
     * 已发货时退款修改状态
     * @param orders
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatebyOrderNumber(List<Order> orders) {
        Order order = new Order();
        order.setOrderNumber(orders.get(0).getOrderNumber());
        order.setOrderState(orders.get(0).getOrderState());
        order.setRefundState(orders.get(0).getRefundState());
        orderMapper.updatebyOrderNumber(order);
        /**
         * 退款表中退款信息修改
         */

//        OrderSettlement orderSettlement = orderSettlementService.getSettlementByOrderId(orders.get(0).getOrderNumber());
        OrderRefund orderRefund = orderRefundService.selectByOrderNumber(orders.get(0).getOrderNumber());
//        OrderItem orderItemList;
//        orderItemList = orders.get(0).getOrderItems().get(0);
//        Order orderList = orders.get(0);
//        orderRefund.setShopId(orderList.getShopId());
//        orderRefund.setOrderId(orderList.getOrderId());
//        orderRefund.setOrderNumber(orderList.getOrderNumber());
//        orderRefund.setOrderAmount(orderList.getActualTotal());
//        orderRefund.setRefundAmount(orderList.getActualTotal());
//        orderRefund.setRefundSn(orderSettlement.getPayNo());
//        orderRefund.setOrderItemId(orderItemList.getOrderItemId());
//        orderRefund.setFlowTradeNo(orderSettlement.getPayNo());
//        orderRefund.setOutRefundNo(orderSettlement.getBizPayNo());
//        orderRefund.setPayType(orderSettlement.getPayType());
//        orderRefund.setUserId(orderSettlement.getUserId());
//        orderRefund.setRefundAmount(orderSettlement.getPayAmount());
//        orderRefund.setRefundReason(orders.get(0).getRefundReason());
//        orderRefund.setRefundExplain(orders.get(0).getRefundExplain());
//        orderRefund.setRefundImg(orders.get(0).getRefundImg());
//        orderRefund.setPhone(orders.get(0).getPhone());
        if(order.getRefundState()==2){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(2);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(1);
        }else if(order.getRefundState()==1){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(1);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(0);
        }else if(order.getRefundState()==3){
            /**
             * 处理状态:1为待审核,2为同意,3为不同意
             */
            orderRefund.setRefundSts(3);
            /**
             * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
             */
            orderRefund.setReturnMoneySts(-1);
        }
        /**
         * 1：仅退款 2：退货退款
         */
        orderRefund.setApplyType(1);
//        orderRefund.setApplyTime(new Date());
        orderRefundService.updateById(orderRefund);
        if(order.getRefundState()==2){
            //退款时,修改返利信息状态为返现失败状态
            RebateRecords rebateRecords = rebateRecordsMapper.getRebateRecords(order.getOrderNumber());
            if(rebateRecords!=null){
                //返利金额
                Double  at =  rebateRecords.getAmount();
                rebateRecords.setStatus(1);
                rebateRecords.setUpdateTime(new Date());
                rebateRecordsService.updateById(rebateRecords);
            }

            List<OrderItem> allOrderItems = new ArrayList<>();
            for (Order order1 : orders) {
                List<OrderItem> orderItem = order1.getOrderItems();
                allOrderItems.addAll(orderItem);
                eventPublisher.publishEvent(new CancelOrderEvent(order1));
            }
            if (CollectionUtil.isEmpty(allOrderItems)) {
                return;
            }
            Map<Long, Integer> prodCollect = new HashMap<>(16);
            allOrderItems.stream().collect(Collectors.groupingBy(OrderItem::getProdId)).forEach((prodId, orderItems) -> {
                int prodTotalNum = orderItems.stream().mapToInt(OrderItem::getProdCount).sum();
                prodCollect.put(prodId, prodTotalNum);
            });
            productMapper.returnStock(prodCollect);

            Map<Long, Integer> skuCollect = new HashMap<>(16);
            allOrderItems.stream().collect(Collectors.groupingBy(OrderItem::getSkuId)).forEach((skuId, orderItems) -> {
                int prodTotalNum = orderItems.stream().mapToInt(OrderItem::getProdCount).sum();
                skuCollect.put(skuId, prodTotalNum);
            });
            skuMapper.returnStock(skuCollect);
        }

    }

    /**
     * 未发货时直接退款修改状态
     * @param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRefund(Order order,Integer refundState) {
        OrderSettlement orderSettlement = orderSettlementService.getSettlementByOrderId(order.getOrderNumber());

        //退款时,修改返利信息状态为返现失败状态
        RebateRecords rebateRecords = rebateRecordsMapper.getRebateRecords(order.getOrderNumber());
        if(rebateRecords!=null){
            //返利金额
            Double  at =  rebateRecords.getAmount();
            rebateRecords.setStatus(1);
            rebateRecords.setUpdateTime(new Date());
            rebateRecordsService.updateById(rebateRecords);
        }

        /**
         * 退款成功订单状态改为关闭
         */
        Integer orderState = 1;
        orderMapper.updateRefund(order.getOrderNumber(),refundState,orderState);

        /**
         * 退款成功,修改拼单状态
         */

        //退款成功,修改拼团状态
        Long ptglid = order.getPtglid();
        String userId = order.getUserId();
        //获取拼团记录
        YxPtgl yxPtgl = yxPtglMapper.selectYxPtglById(ptglid);
        if(yxPtgl!=null){
            yxPtgl.setStatus("2");
            yxPtglMapper.updateYxPtgl(yxPtgl);
        }
        YxCtjl yxCtjl = yxCtjlMapper.getYxCtjlByUserIdAndPtglid(userId,ptglid);
        if(yxCtjl!=null){
            yxCtjl.setStatus("2");
            yxCtjlMapper.updateYxCtjl(yxCtjl);
        }

        /**
         * 退款成功 退回优惠券
         */
        couponRecordMapper.returnCoupon(order.getOrderNumber());
        //查询退款成功的订单
        List<Order> orders = orderService.OrderAndOrderItems(2,order.getOrderNumber());
        OrderRefund orderRefund = new OrderRefund();
        OrderItem orderItem;
        orderItem = orders.get(0).getOrderItems().get(0);
        Order order1 = orders.get(0);
        orderRefund.setShopId(order1.getShopId());
        orderRefund.setOrderId(order1.getOrderId());
        orderRefund.setOrderNumber(order1.getOrderNumber());
        orderRefund.setOrderAmount(order1.getActualTotal());
        orderRefund.setRefundAmount(order1.getActualTotal());
        orderRefund.setRefundSn(orderSettlement.getPayNo());
        orderRefund.setOrderItemId(orderItem.getOrderItemId());
        orderRefund.setFlowTradeNo(orderSettlement.getPayNo());
        orderRefund.setOutRefundNo(orderSettlement.getBizPayNo());
        orderRefund.setPayType(orderSettlement.getPayType());
        orderRefund.setUserId(orderSettlement.getUserId());
        orderRefund.setRefundAmount(orderSettlement.getPayAmount());
        orderRefund.setRefundReason(order.getRefundReason());
        orderRefund.setRefundImg(order.getRefundImg());
        orderRefund.setRefundExplain(order.getRefundExplain());
        orderRefund.setPhone(order.getPhone());
        /**
         * 1：仅退款 2：退货退款
         */
        orderRefund.setApplyType(1);
        /**
         * 处理状态:1为待审核,2为同意,3为不同意
         */
        orderRefund.setRefundSts(2);
        /**
         * 处理退款状态: 0:退款处理中 1:退款成功 -1:退款失败
         */
        orderRefund.setReturnMoneySts(1);
        orderRefund.setApplyTime(new Date());
        orderRefundService.save(orderRefund);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dealOrderSuccess(Order order, String payNo, String bizPayNo, String orderNumber, String puserId) {
        //查询数据库，有没有当前店铺的会员记录，没有的话，就新增会员记录表
        Member member = new Member();
        member.setShopId(order.getShopId());
        member.setUserId(order.getUserId());
        member.setOrderId(order.getOrderId());
        member.setStatus(1l);
        member.setCreateTime(new Date());

        //支付成功修改订单以及拼团状态
        if(order.getPtglid()!=null&&order.getPtglid()!=0l){
            //修改拼团
            Long ptglid = order.getPtglid();
            YxPtgl yxPtgl =  yxPtglMapper.selectYxPtglById(ptglid);
            if(yxPtgl!=null){
                if(yxPtgl.getPtrs()>=yxPtgl.getCtrs()){
                    yxPtgl.setStatus("1");
                    yxPtglMapper.updateYxPtgl(yxPtgl);
                }else{
                    yxPtgl.setStatus("0");
                    yxPtglMapper.updateYxPtgl(yxPtgl);
                }
                //修改拼团记录的信息
                YxCtjl yxCtjl = yxCtjlMapper.getYxCtjlByUserIdAndPtglid(order.getUserId(),ptglid);
                yxCtjl.setStatus("1");
                yxCtjlMapper.updateYxCtjl(yxCtjl);
            }
        }

        //更新order表支付时间
        order.setPayTime(new Date());
        order.setStatus(2);
        orderService.updateById(order);

        //更新支付
        OrderSettlement orderSettlement = orderSettlementService.getSettlementByOrderNumber(orderNumber);
        orderSettlement.setPayNo(payNo);
        orderSettlement.setPayType(1);
        orderSettlementService.saveOrUpdate(orderSettlement);


        Member repeatMember = memberService.getRepeatMember(member);
        if(repeatMember!=null){

        }else{
            memberService.addShopMember(member);
        }

        // 根据内部订单号更新order settlement
        payService.paySuccess(payNo, bizPayNo);

        //获取该订单有没有推荐人
        String tjr = order.getTjr();
        //获取下单用户
        String orderUserId = order.getUserId();
        if(null!=tjr&&!"".equals(tjr)&&!"0".equals(tjr)){
            //查询当前用户
            String userId = userService.getUserByAppConnectId(Long.parseLong(tjr));
            if(!orderUserId.equals(userId)) {
                rebateRecordsService.dealRebate(orderNumber, userId);
            }
        } else if(null!=puserId&&!"".equals(puserId)){
            //根据订单中的商品是否是推广池的商品，根据返利规则对商品进行返利
            rebateRecordsService.dealRebate(orderNumber,puserId);
        }
    }

    /**
     * 后台首页统计
     * @return
     */
    @Override
    public List<OrderStaticsDto> selectTodayStatics(Long shopId) {
        return orderMapper.selectTodayStatics(shopId);
    }
    @Override
    public List<OrderStaticsDto> selectYesterdayStatics(Long shopId) {
        return orderMapper.selectYesterdayStatics(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectPendingOrder(Long shopId) {
        return orderMapper.selectPendingOrder(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectTransOrder(Long shopId) {
        return orderMapper.selectTransOrder(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectCompletedOrder(Long shopId) {
        return orderMapper.selectCompletedOrder(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectRefund(Long shopId) {
        return orderMapper.selectRefund(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectAddMember(Long shopId) {
        return orderMapper.selectAddMember(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectAllMember(Long shopId) {
        return orderMapper.selectAllMember(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectmonthMember(Long shopId) {
        return orderMapper.selectmonthMember(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectThisMonthStatics(Long shopId) {
        return orderMapper.selectThisMonthStatics(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectLastMonthStatics(Long shopId) {
        return orderMapper.selectLastMonthStatics(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectThisWeekStatics(Long shopId) {
        return orderMapper.selectThisWeekStatics(shopId);
    }

    @Override
    public List<OrderStaticsDto> selectLastWeekStatics(Long shopId) {
        return orderMapper.selectLastWeekStatics(shopId);
    }

    @Override
    public  List<OrderStaticsDto> selectWeekDayMoney(Long shopId) {
        return orderMapper.selectWeekDayMoney(shopId);
    }

    @Override
    public  List<OrderStaticsDto> selectMonthDayMoney(Long shopId) {
        return orderMapper.selectMonthDayMoney(shopId);
    }

    /**
     * 更新审核状态
     * @param order
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String refundState(Order order) {
        int refundState = order.getRefundState();
        int orderState = order.getOrderState();
        List<Order> orders = orderService.OrderAndOrderItems(1,order.getOrderNumber());
        if (CollectionUtil.isEmpty(orders)) {
            return null;
        }
        orders.get(0).setRefundState(refundState);
        orders.get(0).setOrderState(orderState);
        orderService.updatebyOrderNumber(orders);
        //退款成功,修改拼团状态
        Long ptglid = orders.get(0).getPtglid();
        String userId = orders.get(0).getUserId();
        //获取拼团记录
        YxPtgl yxPtgl = yxPtglMapper.selectYxPtglById(ptglid);
        if(yxPtgl!=null){
            yxPtgl.setStatus("2");
            yxPtglMapper.updateYxPtgl(yxPtgl);
        }
        YxCtjl yxCtjl = yxCtjlMapper.getYxCtjlByUserIdAndPtglid(userId,ptglid);
        if(yxCtjl!=null){
            yxCtjl.setStatus("2");
            yxCtjlMapper.updateYxCtjl(yxCtjl);
        }
        if(order.getRefundState()==2){
            /**
             * 退款成功退还优惠券
             */
            couponRecordMapper.returnCoupon(order.getOrderNumber());
        }
        return "success";
    }

    @Override
    @Transactional
    public void pushOrderToMeiTuan(Order order) throws Exception {
        //检验美团配送,是否可以配送当前客户
        String checkResult =CheckOrder(order);
        if("0".equals(checkResult)){
            //美团可以派送订单,正式推订单给美团
            String configValue = configService.getValue("delivery_price");
            order.setDistributionFlag(1);
            order.setDistributionType(2);
            if(configValue!=null&&!"".equals(configValue)) {
                order.setDeliveryPrice(Double.valueOf(configValue));
            }
            order.setDvyTime(new Date());
            orderService.saveOrUpdate(order);
            createOrderByShop(order);
        }else{
            //由于各种原因,美团不配送订单
            order.setDistributionFlag(0);
            orderService.saveOrUpdate(order);
        }


    }

    @Override
    public List<Order> listOrderbyDvyTime(Integer orderStatus, DateTime lessThanUpdateTime) {
        return orderMapper.listOrderbyDvyTime(orderStatus, lessThanUpdateTime);
    }

    @Override
    public List<Order> getOrderData(Long shopId, Page<Order> page) {
        List<Order> orderList = orderMapper.getOrderData(new PageAdapter(page), shopId);
        return orderList;
    }

    @Override
    public int insertOrder(Order order){
        return orderMapper.insert(order);
    }

    @Override
    public Order getOrderByPtglid(Long ptglid) {
        return orderMapper.getOrderByPtglid(ptglid);
    }

    public String CheckOrder(Order order) throws Exception{
        String appkey = OpenApiConfig.FORMAL_APP_KEY;
        String secret = OpenApiConfig.FORMAL_SECRET;
        String res=null;
        CheckRequest request = buildMockRequest(appkey,order);

        Map<String, String> params = ParamBuilder.convertToMap(request);
        String sign = SignHelper.generateSign(params, secret);

        params.put("sign", sign);

        try {
            res = HttpClient.post(RequestConstant.ORDER_CHECK_DELIVERY_ABILITY, params);
            CheckOrderResponse response = Json.parseObject(res, CheckOrderResponse.class);
            String code = response.getCode();
            return code;
        } catch (Exception e) {
            throw e;
        }
    }


    private  CheckRequest buildMockRequest(String appkey,Order order) {
        CheckRequest request = new CheckRequest();
        request.setAppkey(appkey);
        request.setTimestamp(DateUtil.unixTime());
        request.setVersion("1.0");
        /**
         * 设置配送服务编码
         *
         * 光速达:4001
         * 快速达:4011
         * 及时达:4012
         * 集中送:4013
         * 当天达:4021
         */
        request.setDeliveryServiceCode(4011);
        // 设置测试门店 id，测试门店的坐标地址为 97235456,31065079（高德坐标），配送范围3km
        request.setShopId(String.valueOf(order.getShopId()));
        // 收件人地址，最长不超过 512 个字符
        Long addorderId = order.getAddrOrderId();
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(addorderId);
        StringBuffer stringBuffer =null;
        double latResult=0.0;
        double lngResult = 0.0;
        if(userAddrOrder!=null){
            Long AddrId = userAddrOrder.getAddrId();
            UserAddr userAddr = userAddrService.getById(AddrId);
            if(userAddr!=null) {
                 stringBuffer = new StringBuffer(userAddr.getProvince());
                 stringBuffer.append(userAddr.getCity()).append(userAddr.getArea()).append(userAddr.getStreet()).append(userAddr.getAddr());
                //收件人经度（高德坐标），高德坐标 *（ 10 的六次方），如 116398419
                double cf = Math.pow(10,6);
                if(userAddr.getLat()!=null) {
                   double lat = Double.valueOf(userAddr.getLat());
                   latResult = lat*cf;
                   double lng = Double.valueOf(userAddr.getLng());
                   lngResult = lng*cf;
                }
                request.setReceiverLng(Integer.valueOf(new Double(lngResult).intValue()));
                //收件人纬度（高德坐标），高德坐标 *（ 10 的六次方），如 39985005
                request.setReceiverLat(Integer.valueOf(new Double(latResult).intValue()));
            }
        }
        request.setReceiverAddress(stringBuffer.toString());
        //预留字段，方便以后扩充校验规则，check_type = 1
        request.setCheckType(1);
        //模拟发单时间，时区为 GMT+8，当前距离 Epoch（1970年1月1日) 以秒计算的时间，即 unix-timestamp。
        request.setMockOrderTime(Long.valueOf(DateUtil.unixTime()));

        return request;
    }

    public void createOrderByShop(Order order) throws Exception{
        String appkey = OpenApiConfig.FORMAL_APP_KEY;
        String secret = OpenApiConfig.FORMAL_SECRET;

        CreateOrderByShopRequest request = buildOrderRequest(appkey,order);

        Map<String, String> params = ParamBuilder.convertToMap(request);
        String sign = SignHelper.generateSign(params, secret);

        params.put("sign", sign);

        try {
            String res = HttpClient.post(RequestConstant.ORDER_CREATE_BY_SHOP, params);
            System.out.println("结果为"+res);
        } catch (Exception e) {
            throw e;
        }


    }

    private CreateOrderByShopRequest buildOrderRequest(String appkey,Order order) {
        CreateOrderByShopRequest request = new CreateOrderByShopRequest();
        request.setAppkey(appkey);
        request.setTimestamp(DateUtil.unixTime());
        request.setVersion("1.0");

        // 设置订单号及配送服务标识
        request.setDeliveryId(Long.valueOf(order.getOrderNumber()));
        request.setOrderId(order.getOrderNumber());

        // 设置订单类型为即时单
        request.setOrderType(OrderType.NORMAL);

        /**
         * 设置配送服务编码
         *
         * 飞速达:4002
         * 快速达:4011
         * 及时达:4012
         * 集中送:4013
         */
        request.setDeliveryServiceCode(4011);

        // 设置测试门店 id，测试门店的坐标地址为 97235456,31065079（高德坐标），配送范围3km
        request.setShopId(String.valueOf(order.getShopId()));

        double latResult=0.0;
        double lngResult = 0.0;
        StringBuffer stringBuffer =null;
        Long addorderId = order.getAddrOrderId();
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(addorderId);
        if(userAddrOrder!=null){
            Long AddrId = userAddrOrder.getAddrId();
            UserAddr userAddr = userAddrService.getById(AddrId);
            if(userAddr!=null) {
                stringBuffer = new StringBuffer(userAddr.getProvince());
                stringBuffer.append(userAddr.getCity()).append(userAddr.getArea()).append(userAddr.getStreet()).append(userAddr.getAddr());
                //收件人经度（高德坐标），高德坐标 *（ 10 的六次方），如 116398419
                double cf = Math.pow(10,6);
                if(userAddr.getLat()!=null) {
                    double lat = Double.valueOf(userAddr.getLat());
                    latResult = lat*cf;
                    double lng = Double.valueOf(userAddr.getLng());
                    lngResult = lng*cf;
                }
                request.setReceiverLng(Integer.valueOf(new Double(lngResult).intValue()));
                //收件人纬度（高德坐标），高德坐标 *（ 10 的六次方），如 39985005
                request.setReceiverLat(Integer.valueOf(new Double(latResult).intValue()));
                // 设置取货人信息，请根据测试门店地址 在测试发单时合理设置送货地址
                request.setReceiverName(userAddr.getReceiver());
                request.setReceiverAddress(stringBuffer.toString());
                request.setReceiverPhone(userAddr.getMobile());
            }
        }


        // 收件人坐标类型
        request.setCoordinateType(0);

        // 设置预计送达时间为1小时以后
        request.setExpectedDeliveryTime(DateUtil.unixTime() + 3600L);

        // 设置门店流水号，门店流水号为一天中单个门店的订单序号，方便骑手线下到门店取货
        request.setPoiSeq(String.valueOf(order.getPoiSeq()));

        // 设置商品详情
        OpenApiGoods openApiGoods = new OpenApiGoods();

        //查找该订单的子订单
        List<OrderItem> itemList = orderItemService.getOrderItemsByOrderNumber(order.getOrderNumber());
        BigDecimal bigDecimal = new BigDecimal("0");
        if(itemList.size()>0){
            List<OpenApiGood> openApiGoodList = new ArrayList<OpenApiGood>();
            for(OrderItem orderItem:itemList){
                OpenApiGood openApiGood = new OpenApiGood();
                // 商品数量
                openApiGood.setGoodCount(orderItem.getProdCount());
                // 商品名称
                openApiGood.setGoodName(orderItem.getProdName());
                // 商品单价
                openApiGood.setGoodPrice(new BigDecimal(orderItem.getPrice()));
                // 商品数量单位
                //openApiGood1.setGoodUnit("盒");
                openApiGoods.setGoods(Arrays.asList(openApiGood));
                //获取skuId
                Long skuId = orderItem.getSkuId();
                Sku sku = skuService.getById(skuId);
                Double weight = sku.getWeight();
                int productCount = orderItem.getProdCount();
                BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(weight));
                if(weight!=null) {
                    bigDecimal1 = bigDecimal1.multiply(new BigDecimal(String.valueOf(productCount))).divide(new BigDecimal(1000));
                }
                bigDecimal = bigDecimal.add(bigDecimal1);
                openApiGoodList.add(openApiGood);
                openApiGoods.setGoods(openApiGoodList);
            }
            request.setGoodsDetail(openApiGoods);
        }
        // 设置商品重量，单位为kg
        request.setGoodsWeight(bigDecimal);
        // 设置备注信息
        request.setNote(order.getRemarks());
        return request;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<Order> groupFailOrders(){
        List<Order> orders = new ArrayList<>();
        YxPtgl yxPtgl = new YxPtgl();
        yxPtgl.setStatus("0");//拼团中
        List<YxPtgl> yxPtglList = yxPtglMapper.getYxPtglList(yxPtgl);
        if(CollectionUtil.isNotEmpty(yxPtglList)){
            for(YxPtgl yxPtgl1:yxPtglList){
                Long goodsid = yxPtgl1.getGoodsid();
                Date ktsjtime = yxPtgl1.getKtsjtime();//开团时间
                YxPtsp yxPtsp = yxPtspMapper.selectYxPtspBygoodsid(goodsid);
                int ctyxsj = yxPtsp.getCtyxsj();//成团有效时间(天)
                Date now = new Date();
                Calendar calendar= new GregorianCalendar();
                calendar.setTime(ktsjtime);
                calendar.add(Calendar.DATE,ctyxsj);
                if(calendar.getTime().compareTo(now)<0){//超过拼团限制时间
                    //修改拼团管理状态为拼团失败
                    yxPtgl1.setStatus("2");//状态 0:拼团中 1：拼团成功 2:拼团失败
                    yxPtglMapper.updateYxPtgl(yxPtgl1);
                    //修改拼团记录状态为拼团失败
                    List<YxCtjl> yxCtjlList =yxCtjlMapper.selectYxCtjlListPtglid(yxPtgl1.getPtglid());
                    if(CollectionUtil.isNotEmpty(yxCtjlList)){
                        for(YxCtjl yxCtjl: yxCtjlList){
                            yxCtjl.setStatus("2");//状态 0:拼团中 1：拼团成功 2:拼团失败
                            yxCtjlMapper.updateYxCtjl(yxCtjl);
                            Long ptglid = yxCtjl.getPtglId();
                            //根据拼团ID查询对应的订单
                            Order order = orderService.getOrderByPtglid(ptglid);
                            //order.setStatus(6);//订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败
                            order.setOrderState(1);
                            order.setRefundState(2);
                            orderService.updateById(order);
                            orders.add(order);
                        }
                    }
                }
            }
        }
        return orders;
    }

    @Override
    public List<Order> getUnprocessedOrder(Long shopId) {
        return orderMapper.getUnprocessedOrder(shopId);
    }

    @Override
    public IPage<Order> getShopDetailId(Page<Order> page) {
        page.setRecords(orderMapper.getShopDetailId(new PageAdapter(page)));
        page.setSize(orderMapper.getShopDetailIdAmount(new PageAdapter(page)));
        return page;
    }


    @Override
    public Double getShopSalesVolume(Long shopId) {
        return orderMapper.getShopSalesVolume(shopId);
    }

    @Override
    public IPage<Order> getShopDetailIdByTime(ShopDetailSalesDto shopDetailSalesDto, Page<Order> page) {
        page.setRecords(orderMapper.getShopDetailIdByTime(shopDetailSalesDto,new PageAdapter(page)));
        page.setSize(orderMapper.getShopDetailIdAmount(new PageAdapter(page)));
        return page;
    }

    @Override
    public Double getShopBusinessVolumeByTime(ShopDetailSalesDto shopDetailSalesDto, Long shopId) {
        return orderMapper.getShopBusinessVolumeByTime(shopDetailSalesDto,shopId);
    }

    @Override
    public List<Order> listOrderNotPay(Integer orderStatus, DateTime lessThanUpdateTime) {
          return orderMapper.listOrderNotPay(orderStatus, lessThanUpdateTime);
    }

    @Override
    @Transactional
    public ShopCartOrderMergerDto insertOrder(List<Product> list,Long cashier,String phoneNumber,String cid) {
        StringBuffer orderProdName = new StringBuffer();
        List<OrderItem> orderItems = new ArrayList<>();
        Double totalPrice = 0.0;
        Long shopId = 0l;
        String userId = null;
        int totalCount = 0;
        //雪花算法生成一个订单号
        String orderNumber = String.valueOf(snowflake.nextId());

        //根据手机号查询会员情况
        Boolean isVip=false;
        if(phoneNumber!=null&&!"".equals(phoneNumber)) {
            //根据手机号码查询对应的用户
            User user = userService.selectUserByPhoneOne(phoneNumber);
            if(user!=null) {
                userId = user.getUserId();
                if(user.getVipLevel()==1){
                    isVip=true;
                }
            }else{
                userId = "88888888888888888888888vip";
            }

            if("-1".equals(phoneNumber)){
                userId = "88888888888888888888888vip";
            }

        }

        //新增order以及orderItem信息
        if(CollectionUtils.isNotEmpty(list)){
            for(Product product:list){
                Long prodId = product.getProdId();
                phoneNumber = product.getPhoneNumber();
                //查询产品详细信息
                Product productDetail = productMapper.getProdcut(prodId);
                shopId = productDetail.getShopId();
                Sku sku = skuMapper.getSkuByProdId(prodId);
                OrderItem orderItem = new OrderItem();
                orderItem.setShopId(productDetail.getShopId());
                orderItem.setOrderNumber(orderNumber);
                orderItem.setProdId(sku.getProdId());
                orderItem.setSkuId(sku.getSkuId());
                orderItem.setSkuName(sku.getSkuName());
                orderItem.setProdCount(product.getCount());
                orderItem.setProdName(sku.getProdName());
                orderItem.setPic(StrUtil.isBlank(sku.getPic()) ? productDetail.getPic() : sku.getPic());
                if(orderItem.getPic()==null){
                    orderItem.setPic("");
                }
                orderItem.setRecTime(new Date());
                orderItem.setCommSts(0);
                orderProdName.append(productDetail.getProdName()).append(",");
                orderItems.add(orderItem);
                orderItem.setUserId(userId);
                //查看产品有没有特殊的策略,价格按照特殊的策略计算
                Long strategyId = productDetail.getStrategyId();
                if(strategyId!=null){
                    PromotionStrategy promotionStrategy = promotionStrategyService.getById(strategyId);
                    if(strategyId==1l&&null!=promotionStrategy){
                        //按照买几送几的策略,进行销售。如果数量少于总数量,则按照原价计算,如果数量多于总数量,多的数量也按照原价计算
                        //购买数量
                        int buyNumber = promotionStrategy.getBuyNumber();
                        //免费数量
                        int freeNumber = promotionStrategy.getFreeNumber();
                        int totalNumber = buyNumber+freeNumber;
                        if(product.getCount()<totalNumber){
                            orderItem.setPrice(productDetail.getPrice());
                            orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),product.getCount()));
                            totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                        }else if(product.getCount()==totalNumber){
                            orderItem.setPrice(productDetail.getPrice());
                            orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),buyNumber));
                            totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                        }else{
                            int extraNumber = product.getCount() -totalNumber;
                            //需要付钱的数量
                            int needToPayNumber = extraNumber + buyNumber;
                            orderItem.setPrice(productDetail.getPrice());
                            orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),needToPayNumber));
                            totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                        }
                    }else if(strategyId==2l&&null!=promotionStrategy){
                            int secondGoodPriceDiscount = promotionStrategy.getSecondGoodPrice();
                            int thirdGoodPriceDiscount = promotionStrategy.getThirdGoodPrice();
                            //第二件商品的价格
                            Double secondGoodPrice = Arith.mul(productDetail.getPrice(),secondGoodPriceDiscount/100);
                            //第三件商品的价格
                            Double thirdGoodPrice = Arith.mul(productDetail.getPrice(),thirdGoodPriceDiscount/100);
                           //根据商品的数量,分别得出不同商品的总价格,总商品数量一般要大于2
                           if(product.getCount()==1){
                               orderItem.setPrice(productDetail.getPrice());
                               orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),product.getCount()));
                               totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                           }else if(product.getCount()==2){
                               //计算两件商品的总价格
                               Double totalGoodsPrice = Arith.add(productDetail.getPrice(),secondGoodPrice);
                               orderItem.setProductTotalAmount(totalGoodsPrice);
                               totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                           }else if(product.getCount()==3){
                               Double totalGoodsPrice = Arith.add(new BigDecimal(productDetail.getPrice()),new BigDecimal(secondGoodPrice),new BigDecimal(thirdGoodPrice));
                               orderItem.setProductTotalAmount(totalGoodsPrice);
                               totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                           }else if(product.getCount()>3){
                               //计算多出来的数量
                               int extraNumber = product.getCount()-3;
                               Double extraNumberPrice = Arith.mul(productDetail.getPrice(),extraNumber);
                               Double totalGoodsDiscountPrice = Arith.add(new BigDecimal(productDetail.getPrice()),new BigDecimal(secondGoodPrice),new BigDecimal(thirdGoodPrice));
                               Double totalGoodsPrice = Arith.add(extraNumberPrice,totalGoodsDiscountPrice);
                               orderItem.setProductTotalAmount(totalGoodsPrice);
                               totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                           }

                    }
                }else{
                    if(isVip && productDetail.getVipDiscount()!=0){
                        Double productPrice = productDetail.getPrice();
                        Double vipDiscount = Arith.div(productDetail.getVipDiscount(),100);
                        orderItem.setPrice(Arith.mul(productPrice,vipDiscount));
                        orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),product.getCount()));
                        totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                        orderItem.setVipPrice(new BigDecimal(Arith.mul(productDetail.getPrice(),productDetail.getVipDiscount()/100)));
                        orderItem.setVipDiscount(productDetail.getVipDiscount());
                    }else if(null!=productDetail.getVipPrice()&&isVip &&productDetail.getVipPrice().compareTo(new BigDecimal("0"))>-1){
                        orderItem.setPrice(productDetail.getVipPrice().doubleValue());
                        orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),product.getCount()));
                        totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                        orderItem.setVipPrice(new BigDecimal(productDetail.getVipPrice().doubleValue()));
                    } else{
                        orderItem.setPrice(productDetail.getPrice());
                        orderItem.setProductTotalAmount(Arith.mul(orderItem.getPrice(),product.getCount()));
                        totalPrice = Arith.add(totalPrice,orderItem.getProductTotalAmount());
                    }
                }
                totalCount = totalCount+product.getCount();
            }
        }

        orderProdName.subSequence(0, Math.min(orderProdName.length() - 1, 100));
        if (orderProdName.lastIndexOf(",") == orderProdName.length() - 1) {
            orderProdName.deleteCharAt(orderProdName.length() - 1);
        }

        //生成order订单信息
        com.yami.shop.bean.model.Order order1 = new com.yami.shop.bean.model.Order();

        order1.setShopId(shopId);
        order1.setOrderNumber(orderNumber);
        // 订单商品名称
        order1.setProdName(orderProdName.toString());
        // 用户id
        order1.setUserId(userId);
        // 商品总额
        order1.setTotal(totalPrice);
        // 实际总额
       // order1.setActualTotal(totalPrice);
        order1.setStatus(OrderStatus.UNPAY.value());
        order1.setUpdateTime(new Date());
        order1.setCreateTime(new Date());
        order1.setIsPayed(0);
        order1.setDeleteStatus(0);
        order1.setProductNums(totalCount);
        order1.setOrderItems(orderItems);
        order1.setCashier(cashier);
        order1.setCid(cid);

        //用户优惠券列表
        List<CouponDto> couponList = couponMapper.getCoupon(userId);
        List<CouponDto> optimumList = null;
        if(couponList.size()>0){
            optimumList = basketService.getOptimumList(couponList, new BigDecimal(totalPrice));
        }
        Double discountMoney = 0.00;
        Double actualTotal = totalPrice;
        Long   recorId = 0l;
        //实际付款金额 = 总价 - 优惠金额;
        if(optimumList!=null&&optimumList.size()>0) {
             discountMoney = optimumList.get(0).getFullAmountReduce();
             actualTotal = Arith.sub(totalPrice,discountMoney);
             recorId = optimumList.get(0).getRecordId();
        }
        order1.setActualTotal(actualTotal);
        List<Order> orderList = new ArrayList<>();
        orderList.add(order1);
        // 插入订单
        orderList.forEach(order -> orderMapper.insert(order));
        List<OrderItem> orderItemList = orderList.stream().flatMap(order -> order.getOrderItems().stream()).collect(Collectors.toList());
        // 插入订单项，返回主键
        orderItemMapper.insertBatch(orderItemList);

        //插入优惠券使用记录
        if(optimumList!=null&&optimumList.size()>0) {
            CouponRecord couponRecord = new CouponRecord();
            couponRecord.setRecordId(recorId);
            couponRecord.setState(2);
            couponRecord.setOrderNumber(orderNumber);
            couponRecordService.updateById(couponRecord);
        }

        ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();
        shopCartOrderMergerDto.setActualTotal(actualTotal);
        shopCartOrderMergerDto.setOrderReduce(discountMoney);
        shopCartOrderMergerDto.setTotalCount(totalCount);
        shopCartOrderMergerDto.setOrderNumber(orderNumber);
        Records record = new Records();
        record.setShopId(shopId);
        record.setOrderNumber(orderNumber);
        // 订单商品名称
        record.setProdName(orderProdName.toString());
        // 用户id
        record.setUserId(userId);
        // 商品总额
        record.setTotal(totalPrice);
        // 实际总额
        // order1.setActualTotal(totalPrice);
        record.setStatus(OrderStatus.UNPAY.value());
        record.setUpdateTime(new Date());
        record.setCreateTime(new Date());
        record.setIsPayed(0);
        record.setDeleteStatus(0);
        record.setProductNums(totalCount);
        record.setOrderItems(orderItems);
        record.setCashier(cashier);
        record.setCid(cid);
        record.setActualTotal(actualTotal);

        shopCartOrderMergerDto.setRecords(record);
        return shopCartOrderMergerDto;

    }

 @Override
    public List<Order> getNotPayOrder(Long cashier) {
        return orderMapper.getNotPayOrder(cashier);
    }

    @Override
    public Order getByOrderNumber(String orderNumber){
        return orderMapper.getByOrderNumber(orderNumber);
    }

    /**
     * 支付撤销 修改订单状态
     * */
    @Override
    public RefundGoodsDto appOrderBackOut(String orderNumber,String merchantCode,String terminalCode,String originalOrderId,
                                          String voidPayment,String appId,String appKey,Long updateBy)
            throws Exception{
        RefundGoodsDto refundGoodsDto = new RefundGoodsDto();
        Order order = orderMapper.getByOrderNumber(orderNumber);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        for(OrderItem orderItem:orderItems){
            Integer prodCount = orderItem.getProdCount();
            Product product=productService.getProductByProdId(orderItem.getProdId());
            product.setTotalStocks(product.getTotalStocks()+prodCount);
            productMapper.updateById(product);
            Sku sku = skuMapper.selectById(orderItem.getSkuId());
            sku.setStocks(sku.getStocks()+prodCount);
            skuMapper.updateById(sku);
        }
        refundGoodsDto.setOrderItems(orderItems);
        refundGoodsDto.setAccount(new BigDecimal(order.getActualTotal()));
        refundGoodsDto.setRefundAccount(order.getProductNums());//退货数量
        refundGoodsDto.setOrderNumber(orderNumber);
        //支付方式 0 现金支付 1 微信支付 2 银联支付 3 账户余额支付
        if(order.getPayType()==0){
            //现金支付
            refundGoodsDto.setIsSuccess(true);
            refundGoodsDto.setRefundType(0);
            orderMapper.appOrderBackOut(orderNumber,updateBy);
        }else if(order.getPayType() == 2){
            /* post参数,格式:JSON */
            JSONObject body = new JSONObject();
            body.put("merchantCode", merchantCode);   // 商户号
            body.put("terminalCode", terminalCode);   // 终端号
            body.put("merchantOrderId", orderNumber);  // 商户订单号,这里得获取原交易的商户订单号
//            body.put("originalOrderId", originalOrderId);    // 银商订单号
//          body.put("limitCrossDevice", true); // 是否限制跨终端,true不可以跨终端,false:可以跨终端
//          body.put("bizIdentifier", "业务标识");// 业务标识,一般不上送
            String send = send(voidPayment, body.toString(),appId,appKey);
            JSONObject resultJson = new JSONObject(send);
            if(resultJson.getString("errCode").equals("00")){
                refundGoodsDto.setIsSuccess(true);
                refundGoodsDto.setResult(send);
                orderMapper.appOrderBackOut(orderNumber,updateBy);
            }else{
                refundGoodsDto.setIsSuccess(false);
                refundGoodsDto.setErrInfo(resultJson.getString("errInfo"));
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return refundGoodsDto;
            }
        }else if(order.getPayType() == 3){
            //账户余额支付，退还到原来的账户
            User user = userMapper.selectById(order.getUserId());
            user.setAccount(user.getAccount() +order.getActualTotal());
            userMapper.updateById(user);
            refundGoodsDto.setRefundType(1);
            refundGoodsDto.setIsSuccess(true);
            orderMapper.appOrderBackOut(orderNumber,updateBy);
        } else{
            refundGoodsDto.setIsSuccess(false);
            refundGoodsDto.setErrInfo("订单支付类型异常，请联系管理员");
        }

        return refundGoodsDto;
    }
    /**
     * 发送请求
     * */
    public String send(String url,String entity,String appId,String appKey) throws Exception{
        authorization = getOpenBodySig(appId,appKey,entity);
        System.out.println("authorization"+authorization);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Authorization", authorization);
        StringEntity se = new StringEntity(entity, "UTF-8");
        se.setContentType("application/json");
        System.out.println("se"+se);
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity1 = response.getEntity();
        String resStr = null;
        if (entity1 != null) {
            resStr = EntityUtils.toString(entity1, "UTF-8");
        }
        httpClient.close();
        response.close();
        return resStr;
    }
    /**
     * open-body-sig方式获取到Authorization 的值
     *
     * @param appId
     * @param appKey
     * @param body
     * @return
     * @throws Exception
     */
    public static String getOpenBodySig(String appId, String appKey, String body) throws Exception {
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());   // eg:20190227113148
        String nonce = UUID.randomUUID().toString().replace("-", ""); // eg:be46cd581c9f46ecbd71b9858311ea12
        byte[] data = body.getBytes("UTF-8");
        System.out.println("data:\n" + body);
        InputStream is = new ByteArrayInputStream(data);
        String bodyDigest = testSHA256(is); // eg:d60bc3aedeb853e2a11c0c096baaf19954dd9b752e48dea8e919e5fb29a42a8d
        System.out.println("bodyDigest:\n" + bodyDigest);
        String str1_C = appId + timestamp + nonce + bodyDigest; // eg:f0ec96ad2c3848b5b810e7aadf369e2f + 20190227113148 + be46cd581c9f46ecbd71b9858311ea12 + d60bc3aedeb853e2a11c0c096baaf19954dd9b752e48dea8e919e5fb29a42a8d
        System.out.println("str1_C:" + str1_C);
        byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());
        String localSignatureStr = Base64.encodeBase64String(localSignature);   // Signature
        System.out.println("Authorization:\n" + "OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"\n");
        return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
    }
    /**
     * 进行加密
     *
     * @param is
     * @return 加密后的结果
     */
    private static String testSHA256(InputStream is) {
        try {
            return DigestUtils.sha256Hex(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }



    @Override
    public List<Order> getAllOrderByshopId(Long shopId,int pageNumber,int startpageNumber) {
        return orderMapper.getAllOrderByshopId(shopId,pageNumber,startpageNumber);
    }
    /**
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data);
    }

    @Override
    public List<Order> getDpsOrder(Long shopId, int pageNumber, int startpageNumber) {
        return orderMapper.getDpsOrder(shopId,pageNumber,startpageNumber);
    }

    @Override
    public List<Order> getDkdOrder(Long shopId, int pageNumber, int startpageNumber) {
        return orderMapper.getDkdOrder(shopId,pageNumber,startpageNumber);
    }

    @Override
    @Transactional
    public String paySuccessByCash(BigDecimal actualCollection,String orderNumber) {
        //支付成功,修改订单状态
        Order order = orderService.getOrderByOrderNumber(orderNumber);
        //获取订单状态,当只有待支付订单的时候,才能支付成功
        int status = order.getStatus();
        if(status==1) {
            order.setStatus(5);
            order.setPayType(0);
            order.setActualCollection(actualCollection);
            //找零

            if(order.getMixedPayment()==1){
                //计算需要账户余额需要支付的金额
                BigDecimal oldAccount = order.getOldAccountPay();
                if(oldAccount.compareTo(new BigDecimal("0"))>-1){
                    Double remainAccount = Arith.sub(order.getActualTotal(),oldAccount.doubleValue());
                    order.setCashPay(new BigDecimal(remainAccount));
                    String userId = order.getUserId();
                    Long shopId = order.getShopId();
                    OldUser oldUser = oldUserService.getOldUserByShopId(userId,shopId);
                    BigDecimal account = new BigDecimal(0.00);
                    if(oldUser!=null){
                        account = oldUser.getAccount();
                    }
                    BigDecimal oldAccountPaybd =order.getOldAccountPay().setScale(2,BigDecimal.ROUND_HALF_UP);
                    if(account.compareTo(oldAccountPaybd)>-1){
                        Double newOldAccount = Arith.sub(account.doubleValue(),oldAccountPaybd.doubleValue());
                        oldUser.setAccount(new BigDecimal(newOldAccount));
                        oldUserService.saveOrUpdate(oldUser);
                    }

                    //计算实际找零金额
                    Double giveChange = Arith.sub(actualCollection.doubleValue(),remainAccount);
                    order.setGiveChange(new BigDecimal(giveChange));
                    order.setPayType(5);
                }
//                BigDecimal userAccount = order.getNewAccountPay();
//                if(userAccount!=null) {
//                    if (userAccount.compareTo(new BigDecimal(0)) > -1) {
//                        Double remainAccount = Arith.sub(order.getActualTotal(), userAccount.doubleValue());
//                        order.setCashPay(new BigDecimal(remainAccount));
//
//                        String userId = order.getUserId();
//                        User user = userService.getUserByUserId(userId);
//                        Double account = user.getUserAccount();
//                        BigDecimal newAccountPaybd = order.getNewAccountPay().setScale(2, BigDecimal.ROUND_HALF_UP);
//                        if (new BigDecimal(account).compareTo(newAccountPaybd) > -1) {
//                            Double newAccount = Arith.sub(account, newAccountPaybd.doubleValue());
//                            user.setUserAccount(newAccount);
//                            userService.saveOrUpdate(user);
//                        }
//
//                        //计算实际找零金额
//                        Double giveChange = Arith.sub(actualCollection.doubleValue(),remainAccount);
//                        order.setGiveChange(new BigDecimal(giveChange));
//                    }
//                }
            }else{
                Double giveChange = Arith.sub(order.getActualTotal(),actualCollection.doubleValue());
                order.setGiveChange(new BigDecimal(giveChange));
            }
            orderService.saveOrUpdate(order);

            //商品库存数量减去已支付成功的商品数量
            List<OrderItem> orderItemList = orderItemService.getOrderItemsByOrderNumber(orderNumber);
            if (CollectionUtils.isNotEmpty(orderItemList)) {
                for (OrderItem orderItem : orderItemList) {
                    Long prodId = orderItem.getProdId();
                    int prodCount = orderItem.getProdCount();
                    //查询对应的商品数量
                    Product product = productService.getProductByProdId(prodId);
                    int totalStocks = product.getTotalStocks();
                    int remainStock = totalStocks - prodCount;
                    product.setTotalStocks(remainStock);
                    productService.saveOrUpdate(product);

                    //sku库存量修改
                    Long skuId = orderItem.getSkuId();
                    Sku sku = skuService.getSkuBySkuId(skuId);
                    int stocks = sku.getStocks();
                    //剩余库存量
                    int leftStock = stocks - prodCount;
                    sku.setStocks(leftStock);
                    skuService.saveOrUpdate(sku);
                }
            }
        }


        return orderNumber;

    }

    @Override
    public List<Order> getOrderListByEnterTime(String lessThanUpdateTime) {
        return orderMapper.getOrderListByEnterTime(lessThanUpdateTime);
    }

    @Override
    public List<Order> getOrderListByTodayShopAState(Long shopId,Date startTime,Date endTime) {
        return orderMapper.getOrderListByTodayShopAState(shopId,startTime,endTime);
    }

}
